'''
Created on 18/11/2011

@author: godinho
'''

import rsi
import sumolib.net
import math

def guessMainFlushDirection(phase, node):
    
    nodeSource = phase.getPrevious();   
    
    a = node.getY() - nodeSource.getY()
    b = nodeSource.getX() - node.getX()
    c = node.getX()*nodeSource.getY() - nodeSource.getX()*node.getY()
    
    minDist = 99999
    selectedNode = 0
    
    for i in range(phase.getLinkCount()) :
        link = phase.getLink(i)
        nodeTarget = link.getTo()
        distancia = math.fabs(a*nodeTarget.getX() + b*nodeTarget.getY() + c)/math.sqrt(math.pow(a,2)+math.pow(b,2));
        
        if distancia < minDist:
            minDist = distancia
            selectedNode = nodeTarget
            
    phase.setNext(selectedNode);
            
            
        

def buildNetwork(sumoNetworkFile) :
    sumoNet = sumolib.net.readNet(sumoNetworkFile, withPrograms=1);
    
    rsiNet = rsi.Network();
    
    for node in sumoNet._nodes :
        rsiNode = rsiNet.createNode(str(node._id))
        coord = node._coord;
        rsiNode.setX(int(coord[0]));
        rsiNode.setY(int(coord[1]));
        rsiNet.addNode(rsiNode)
                

    for edge in sumoNet._edges :
        nodeFrom = rsiNet.getNodeByName(str(edge._from._id));
        nodeTo   = rsiNet.getNodeByName(str(edge._to._id));
        rsiEdge = rsiNet.createEdge(nodeFrom, nodeTo, str(edge._id));
        rsiEdge.setMeanSpeed(edge.getSpeed());
        rsiEdge.setNumLanes(edge.getLaneNumber());
        rsiNet.addEdge(rsiEdge);
        
    for node in sumoNet._nodes :
        if node._id in sumoNet._id2tls :
            rsiNode = rsiNet.getNodeByName(str(node._id));
            tls = sumoNet._id2tls[str(node._id)]
            
            """Store id for links that was already inserted"""
            linksStr = []
            rsiLinkList = []
            
            linkStatusIndex = []
            linkIndex = -1
            
            for connection in tls._connections :
                linkIndex = linkIndex + 1
                inLane = connection[0];
                outLane = connection[1];
                fromEdge = inLane._edge;
                toEdge = outLane._edge;
                
                linkId = "%s_%s" % (str(fromEdge._id), str(toEdge._id));
                
                if linkId in linksStr :
                    continue;
                
                linkStatusIndex.append(connection[2])
                linksStr.append(linkId);
                
                fromNode = fromEdge._from;
                toNode = toEdge._to;
                rsiFromNode = rsiNet.getNodeByName(str(fromNode._id));
                rsiToNode = rsiNet.getNodeByName(str(toNode._id));
                link = rsiNet.createLink(rsiFromNode, rsiToNode);
                rsiNode.addLink(link);
                rsiLinkList.append(link)
                
            programs = tls._programs
            program = programs[unicode("0")]

            phases = program._phases
            
            for phase in phases:
                rsiPhase = rsiNet.createPhase()
                state = phase[0]
                i = 0
                for link in rsiLinkList:
                    linkStatus = state[linkStatusIndex[i]]
                    rsiPhase.addLink(link, ord(linkStatus))
                    i = i+1
                    
                testFrom = rsiPhase.getPrevious()
                if testFrom is None:
                    print "Motherfucking phase {0} of node {1} is nil".format(phase, rsiNode.getId())   
                     
                rsiPhase.setDuration(phase[1]);
                guessMainFlushDirection(rsiPhase, rsiNode)
                rsiNode.addPhase(rsiPhase)
                
                
    return rsiNet;
        